package com.example.demo.security;

import com.example.demo.core.filter.VerifyFilter;
import com.example.demo.security.provider.CustomAuthenticationProvider;
import com.example.demo.security.service.CustomUserDetailsService;
import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

/**
 * @author xkx
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private DataSource dataSource;

  @Autowired
  private CustomUserDetailsService customUserDetailsService;

  @Autowired
  private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource;

  @Autowired
  private CustomAuthenticationProvider customAuthenticationProvider;


  @Bean
  public PersistentTokenRepository persistentTokenRepository() {
    JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
    jdbcTokenRepository.setDataSource(dataSource);
    return jdbcTokenRepository;
  }

  @Override
  protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder)
      throws Exception {
    authenticationManagerBuilder.authenticationProvider(customAuthenticationProvider);
    authenticationManagerBuilder.userDetailsService(customUserDetailsService)
        .passwordEncoder(new BCryptPasswordEncoder());
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
        .antMatchers("/weixin/auth", "/home").permitAll()
        // .antMatchers("/", "/home").permitAll()
        .antMatchers("/getVerifyCode").permitAll()
        .antMatchers("/admin").hasRole("ADMIN")
        //.anyRequest().authenticated()
        .and()
        .csrf().disable()
        .formLogin()
        .loginPage("/login")
        .defaultSuccessUrl("/").permitAll()
        //.failureForwardUrl("/error.html")
        .failureUrl("/login/error")
        .authenticationDetailsSource(authenticationDetailsSource)
        .permitAll()
        .and()
        .addFilterBefore(new VerifyFilter(), UsernamePasswordAuthenticationFilter.class)
        .logout()
        .permitAll()
        .and().rememberMe()
        .tokenRepository(persistentTokenRepository())
        .tokenValiditySeconds(60)
        .userDetailsService(userDetailsService());
  }

  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//    auth
//        .inMemoryAuthentication()
//        .passwordEncoder(new BCryptPasswordEncoder())
//        .withUser("xkx").password(new BCryptPasswordEncoder().encode("xkx")).roles("USER")
//        .and()
//        .withUser("admin").password(new BCryptPasswordEncoder().encode("admin"))
//        .roles("USER", "ADMIN");
  }
}